/*!	 trees/layergrouptreestore.h
**	 Template Header
**
**	Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
**
**	This package is free software; you can redistribute it and/or
**	modify it under the terms of the GNU General Public License as
**	published by the Free Software Foundation; either version 2 of
**	the License, or (at your option) any later version.
**
**	This package is distributed in the hope that it will be useful,
**	but WITHOUT ANY WARRANTY; without even the implied warranty of
**	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
**	General Public License for more details.
**
*/

#ifndef __SYNFIG_STUDIO_LAYERGROUPTREESTORE_H
#define __SYNFIG_STUDIO_LAYERGROUPTREESTORE_H

#include <gtkmm/treestore.h>
#include <synfigapp/canvasinterface.h>
#include <synfig/value.h>
#include <synfig/valuenode.h>
#include <gtkmm/treeview.h>

namespace studio
{

class LayerGroupTreeStore :  public Gtk::TreeStore
{


public:
    typedef std::list<synfig::Layer::Handle> LayerList;

    class Model : public Gtk::TreeModel::ColumnRecord
    {
    public:
        Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
        Gtk::TreeModelColumn<Glib::ustring> label;
        Gtk::TreeModelColumn<Glib::ustring> tooltip;

        Gtk::TreeModelColumn<Glib::ustring> group_name;
        Gtk::TreeModelColumn<Glib::ustring> parent_group_name;

        Gtk::TreeModelColumn<synfig::Canvas::Handle> canvas;

        Gtk::TreeModelColumn<bool>						active;
        Gtk::TreeModelColumn<bool>						is_layer;
        Gtk::TreeModelColumn<bool>						is_group;
        Gtk::TreeModelColumn<synfig::Layer::Handle>		layer;

        Gtk::TreeModelColumn<LayerList>		all_layers;
        Gtk::TreeModelColumn<LayerList>		child_layers;

        Model()
        {
            add(icon);
            add(label);
            add(group_name);
            add(parent_group_name);
            add(canvas);
            add(tooltip);
            add(active);
            add(layer);
            add(is_layer);
            add(is_group);
            add(all_layers);
            add(child_layers);
        }
    };



public:

    // TreeModel for the layers
    const Model model;

    bool rebuilding;



private:

    etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;

    Glib::RefPtr<Gdk::Pixbuf> layer_icon;
    Glib::RefPtr<Gdk::Pixbuf> group_icon;



private:



private:

    virtual void set_value_impl(const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
    virtual void  get_value_vfunc(const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;

    virtual bool  row_draggable_vfunc(const TreeModel::Path& path)const;
    virtual bool  drag_data_get_vfunc(const TreeModel::Path& path, Gtk::SelectionData& selection_data)const;
    virtual bool  drag_data_delete_vfunc(const TreeModel::Path& path);
    virtual bool  drag_data_received_vfunc(const TreeModel::Path& dest, const Gtk::SelectionData& selection_data);
    virtual bool  row_drop_possible_vfunc(const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const;

    void on_group_pair_added(synfig::String group, etl::handle<synfig::Layer> layer);
    void on_group_pair_removed(synfig::String group, etl::handle<synfig::Layer> layer);

    void on_activity();



private:

    bool on_layer_tree_event(GdkEvent *event);

    void on_layer_new_description(synfig::Layer::Handle handle, synfig::String desc);

    void on_layer_status_changed(synfig::Layer::Handle handle, bool);

    bool find_layer_row_(const synfig::Layer::Handle &handle, synfig::Canvas::Handle canvas, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev);

    bool find_group_row_(const synfig::String &group, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev);

    bool on_group_removed(synfig::String group);
    bool on_group_changed(synfig::String group);



public:

    LayerGroupTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
    ~LayerGroupTreeStore();

    Gtk::TreeRow on_group_added(synfig::String group);
    etl::loose_handle<synfigapp::CanvasInterface> canvas_interface()
    {
        return canvas_interface_;
    }
    etl::loose_handle<const synfigapp::CanvasInterface> canvas_interface()const
    {
        return canvas_interface_;
    }
    etl::loose_handle<synfigapp::CanvasInterface> get_canvas_interface()const
    {
        return canvas_interface_;
    }

    bool find_layer_row(const synfig::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);

    bool find_group_row(const synfig::String &group, Gtk::TreeModel::Children::iterator &iter);

    bool find_prev_layer_row(const synfig::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);

    void rebuild();

    void refresh();

    void refresh_row(Gtk::TreeModel::Row &row);

    void set_row_layer(Gtk::TreeRow &row, synfig::Layer::Handle &handle);

    static bool search_func(const Glib::RefPtr<TreeModel>&, int, const Glib::ustring&, const TreeModel::iterator&);



public:

    static Glib::RefPtr<LayerGroupTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);

}; // END of class LayerGroupTreeStore

}; // END of namespace studio

#endif